#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 19-5-25 下午7:14
# @Author  : Jason
# @Site    : 
# @File    : views.py
# @Software: PyCharm
import random
import re
from datetime import datetime

from flask import *
from info import constants, redis_store, db
from info.libs.yuntongxun.sms import CCP
from info.models import User
from info.utils.response_code import RET
from . import passport_blu
from info.utils.captcha.captcha import captcha

@passport_blu.route('/logout')
def logout():
   #退出登录
    #pop是移除session中的数据dict
    #pop会有一个返回值,如果要移除的key不存在,就返还None
    session.pop('user_id',None)
    session.pop('mobile',None)
    session.pop('nick_name',None)
    session.pop('is_admin', None)
    return jsonify(errno=RET.OK,errmsg='退出成功')

@passport_blu.route('/login',methods=['POST'])
def login():
    """
    1.获取所有参数
    2校验参数
        2.1.检查是否获得所有参数
        2.2检查密码是否正确
        2.3校验密码是否正确
    4.保存用户的登录信息
    5.响应

    """
    # 1获取参数
    params_dict =request.json
    mobile =params_dict.get('mobile')
    passport = params_dict.get("passport")
    #  2校验参数
    #2.1.检查是否获得所有参数
    if not all([mobile,passport]):
        return jsonify(errno=RET.PARAMERR,errmsg='输入参数有误')
    # 2.2校验手机号码是否正确
    if not re.match('1[35678]\\d{9}', mobile):
        return jsonify(errno=RET.PARAMERR, errmsg='手机格式不正确')
    # 2.3校验密码是否正确
    try:
        #查询出当前是否有指定手机号的用户
        user=User.query.filter(User.mobile==mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='数据查询的错误')
    # 判断用户是否存在
    if not user:
        return jsonify(errno=RET.NODATA,errmsg='用户不存在')
    #校验获取的密码是否与数据库查询的用户密码一致
    if not user.check_password(passport):
        return  jsonify(errno=RET.PWDERR,errmsg='用户或者密码错误')

    session['user_id']=user.id
    session['mobile']=user.mobile
    session['nick_name']=user.nick_name
    #设置当前用户最后一次登录时间
    user.last_login=datetime.now()
    # 如果视图函数中,对模型上的属性进行修改时那么需要commit到数据库保存
    #但是其实可以不用自己去写db.seesion.commit(),前提是对SQLALchemmy有过相关配置
    # try:
    #     db.session.commit()
    # except Exception as e:
    #     db.session.rollback()
    #     current_app.logger.error(e)


    return jsonify(errno=RET.OK,errmsg='登录成功')

@passport_blu.route('/register',methods=['POST'])
def register():
    """
    注册的逻辑
    1.获取参数/手机号码/短信验证码/密码
    2.校验参数
        2.1校验手机号码
        2.3将服务器保存的校验码内容与获取的短信验证码进行比较
    3.初始化用户模型并且赋值
    4.将用户模型添加到数据库
    5.在session中保存用户数据表示当前已经登陆
    """
    #1.获取参数
    param_dict =request.json
    mobile = param_dict.get('mobile')
    smscode =param_dict.get('smscode')
    password =param_dict.get('password')
    #2.校验参数
    # 2.1检查参数是否全部传过来
    if not all([mobile,smscode,password]):
        return jsonify(errno=RET.PARAMERR,errmsg='参数错误')
    #2.2校验手机号码是否正确
    if not re.match('1[35678]\\d{9}',mobile):
        return jsonify(errno=RET.PARAMERR,errmsg='手机格式不正确')
   #2.3获取redis中存储在服务器中的短信验证码值并与浏览器中度取到的验证码值进行比较
    try:
        real_sms_code=redis_store.get('SMS_'+mobile)
    except Exception as e:
        current_app.logger.error(e)
    if not real_sms_code:
        return  jsonify(errno=RET.DBERR,errmsg='数据查询失败')
    if real_sms_code!=smscode:
        return jsonify(errno=RET.DATAERR,erromsg='验证码输入错误')
    #3.初始化用户模型并且赋值
    user=User()
    user.mobile =mobile
    user.nick_name =mobile
    user.last_login =datetime.now()
    #TODO对密码进行处理
    # 需求:在设置password的时候,去对password进行加密,并且将加密结果赋值给user.password_hash
    user.password=password
    #4.将用户数据添加到数据库
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR,errmsg='数据保存失败')
    #5.往session中保存数据表示当前已经登陆
    session["user_id"]=user.id
    session['mobile']=user.mobile
    session['nick_name']=user.nick_name
    #返还响应
    return jsonify(errno=RET.OK,errmsg='注册成功')

@passport_blu.route('/sms_code',methods=['POST'])
def send_sms_code():
    """
    发送短信验证码的逻辑
    1.获取参数:手机号码/图片验证码的内容/图片验证码的编码
    2.校验参数
        2.1检查参数是否全部传过来
        2.2判断用户输入的手机格式是否正确
        2.3检查用户输入的图片验证码是否正确(与存储在redis里真是验证码进行比较)
    3.随机生成短信验证码
    4.使用第三方SDK进行发送短信验证码

    """
    #{'mobile':"18811111111",'image_code':'AAAA',"image_code_id":'u23'}
    # 1.获取参数:手机号码/图片验证码的内容/图片验证码的编码
    params_dict =request.json#等同于params_dict=json.loads(request.data)
    mobile= params_dict.get("mobile")
    image_code=params_dict.get('image_code')
    image_code_id =params_dict.get('image_code_id')
    #2.校验参数
    #2.1检查参数是否全部传过来
    if not all([mobile,image_code,image_code_id]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数有误")
    #2.2判断用户输入的手机格式是否正确
    if not  re.match('1[35678]\\d',mobile):
        return jsonify(errno=RET.PARAMERR,errmsg='手机格式不正确')
    #2.3检查用户输入的图片验证码是否正确(首先校验存储在redis里的验证码是否过期然后真再与获得验证码进行比较)
    try :
        real_image_code =redis_store.get("ImageCodeId_"+image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='数据查询错误')

    if not real_image_code:
        return jsonify(errno=RET.NODATA,errmsg="图片验证码过期")

    if real_image_code.upper()!=image_code.upper():
        return jsonify(errno=RET.DATAERR,errmsg='验证码输入错误')
    #3.随机生成短信验证码
    sms_code_str ="%06d"%random.randint(0,999999)
    current_app.logger.debug("短信验证码的内容:%s"%sms_code_str)
    #4.使用第三方SDK进行发送短信验证码
    result=CCP().send_template_sms(mobile,[sms_code_str,constants.SMS_CODE_REDIS_EXPIRES/60],'1')
    if result !=0:
        #代表发送不成功
        return  jsonify(errno =RET.THERDERR ,errmsg ='发送短信失败')
    try:
        redis_store.set('SMS_'+mobile,sms_code_str,constants.SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
    #告知发送结果
    return jsonify(errno=RET.OK ,errmsg='发送成功')



@passport_blu.route('/image_code')
def get_image_code():
    '''
    生成图片验证码并返回
    1.取参数
    2.判断参数是否有值
    3.生成图片验证码
    4.保存图片验证码内容到redis
    5.返还验证码图片
    '''
    # 1.取到参数
    # args:取到url中后面的参数
    image_code_id =request.args.get('imageCodeId',None)#1.imageCodeId
    # 判断参数是否有值
    if not image_code_id:
        return abort(403)
   # 3.生成图片验证码
    name,text,image =captcha.generate_captcha()
    current_app.logger.debug("图片验证码%s:"%text)
    # 4.保存图片验证码内容到redis
    try :
        redis_store.set('ImageCodeId_'+image_code_id,text,constants.IMAGE_CODE_REDIS_EXPIRES)
    except Exception as e:
       current_app.logger.error(e)
       abort(500)#/home
    # 返还图片验证码
    response =make_response(image)
    # 设置数据的类型,以便浏览器更加识别其是什么类型
    response.headers['Content_Type']='image/jpg'#1.headders/Content_Type
    return response